package org.wenhua.yuan.and.module_flutter.flutterM1.bridge

import android.content.Context
import android.util.Log
import io.flutter.embedding.engine.loader.FlutterLoader
import java.io.File
/**
 * Flutter 热更新方案：动态加载.so，
 * 利用反射将新的flutter的代码so路径，成功注入到原flutter的so加载流程中。
 * 从而实现动态加载so的热更新。
 * */
class JFlutterLoader :FlutterLoader() {

    companion object {
        const val FIX_SO = "libappfix.so" // 原为 "libflutter.so"
        private var instance:JFlutterLoader? = null
            get() {
                if (field == null) {
                    field = JFlutterLoader()
                }
                return field
            }

        fun get():JFlutterLoader {
            return instance!!
        }
    }


    /**
     * 反射修改原'liabapp.so'文件指向。
     * 跟随初始化的流程，代码是在ensureInitializationComplete中进行加载，
     * 同时其地址是存储在flutterApplicationInfo中*/
    override fun ensureInitializationComplete(
        applicationContext: Context,
        args: Array<out String>?
    ) {

        val path = applicationContext.filesDir
        val soFile = File(path, FIX_SO)
        if (soFile.exists()) {
            try {
                // 利用反射，若so文件存在，反射FlutterLoader下的aotSharedLibraryName，达到修改libapp.so名称目的。
                // 从而达到修改FlutterLoader加载原libapp.so文件路径的目的。
                // 这里FlutterApplicationInfo.aotSharedLibraryName就是我们写的dart代码so名称(我们平时开发主要代码都是写在libapp.so中)
                val field = FlutterLoader::class.java.getDeclaredField("aotSharedLibraryName")
                field.isAccessible = true
                field[this] = soFile.absolutePath
                Log.d("JFlutter", "JFlutterLoader-ensureInitializationComplete")
            }catch (e:Exception)  {
                e.printStackTrace()
                Log.d("JFlutter", "JFlutterLoader-ensureInitializationComplete-Exception")
            }
        }
        // 在FlutterJNI.nativeInit之前将so路径替换好
        super.ensureInitializationComplete(applicationContext, args)
    }


}